package virtorina.server.rpc;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import virtorina.client.room.dto.ChatMsgDTO;
import virtorina.client.room.dto.InfoDTO;
import virtorina.client.room.dto.QuestionDTO;
import virtorina.client.room.dto.UserDTO;
import virtorina.client.room.rpc.GWTService4Room;
import virtorina.server.Base;
import virtorina.server.domain.ChatMsg;
import virtorina.server.domain.Info;
import virtorina.server.domain.Question;
import virtorina.server.domain.User;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class GWTService4RoomImpl extends RemoteServiceServlet implements
		GWTService4Room {

	private static final long serialVersionUID = 1L;

	
	@Override
	public String getName(Integer RoomID){
		return Base.getName(RoomID);
	}
	@Override
	public boolean add(Long RoomID, String msg) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		if (UserID == null) {
			return false;
		}
		ChatMsg chatmsg = new ChatMsg(RoomID, msg, UserID, new Date());
		return Base.getRoom(chatmsg.getRoomID().intValue()).addMessage(chatmsg);

	}

	@Override
	public ArrayList<ChatMsgDTO> getNewMessage(int RoomID) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		List<ChatMsg> msgs = Base.getRoom(RoomID).getMessages(UserID);
		ArrayList<ChatMsgDTO> res = new ArrayList<ChatMsgDTO>();
		for (int i = 0; i < msgs.size(); i++) {
			ChatMsg chatMsg = msgs.get(i);
			res.add(new ChatMsgDTO(chatMsg.getRoomID(), chatMsg.getMsg(),
					chatMsg.getUserID(), chatMsg.getUserName(), chatMsg
							.getDate()));
		}
		return res;
	}

	@Override
	public LinkedList<UserDTO> getNewUsers(int RoomID) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		List<User> users = Base.getRoom(RoomID).getComes(UserID);
		LinkedList<UserDTO> res = new LinkedList<UserDTO>();
		for (User u : users) {
			res.add(new UserDTO(u.getUserID(), u.getName()));
		}
		return res;
	}

	@Override
	public UserDTO getUser(int RoomID) {
		boolean ok = true;
		UserDTO udto;
		Long userID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		this.getThreadLocalRequest().getSession()
				.setAttribute("RoomID", RoomID);
		// Если сессия создана
		if (userID != null) {
			User u;
			u = Base.getRoom(RoomID).getUser(userID);
			// Если пользователь не в комнате
			if (u == null) {
				// Если сессия не анонимного пользователя
				if (userID >= 0) {
					u = User.getUser(userID);
					ok = Base.getRoom(RoomID).setNewUser(u);
					// Если сессия анонимного пользователя
				} else {
					userID = Base.getRoom(RoomID).setAnonym();
					this.getThreadLocalRequest().getSession()
							.setAttribute("user", userID);
					u = new User(userID, "Anonymous");
				}
				udto = new UserDTO(userID, u.getName());
				// Если пользователь в базе
			} else {
				Base.getRoom(RoomID).refreshUser(u);
				udto = new UserDTO(userID, u.getName());
			}
			// Если сессия не создана
		} else {
			userID = Base.getRoom(RoomID).setAnonym();
			this.getThreadLocalRequest().getSession()
					.setAttribute("user", userID);
			udto = new UserDTO(userID, "Anonymous");
		}
		if (ok) {
			return udto;
		} else {
			return null;
		}
	}

	@Override
	public int getUpdates(int RoomID) {
		// System.out.println("upd from " + RoomID);
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		if (UserID == null) {
			return 0;
		} else {
			return Base.getRoom(RoomID).getNews(UserID);
		}

	}

	@Override
	public boolean validate(String nick) {
		return User.isFreeName(nick);
	}

	@Override
	public String updateName(String text, int RoomID) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		User u = User.getUser(UserID);
		u.setName(text);
		User.updateUser(u);
		Base.getRoom(RoomID).UpdateName(text, UserID);
		Base.getRoom(RoomID).leave(UserID);
		Base.getRoom(RoomID).setNewUser(u);

		return text;

	}

	@Override
	public void leave(int RoomID) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		Base.getRoom(RoomID).leave(UserID);
	}

	@Override
	public LinkedList<Long> getLeaveUsers(int RoomID) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		LinkedList<Long> users = Base.getRoom(RoomID).getleavers(UserID);
		return users;
	}

	@Override
	public QuestionDTO getQuestion(int RoomID) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		Question tq = Base.getRoom(RoomID).getQuestion(UserID);
		if (tq.getNumOfRank() == null) {
			tq.setNumOfRank(0);
		}
		QuestionDTO qd = new QuestionDTO(tq.getTime() - new Date().getTime(),
				tq.getQuestion(), tq.getDuration(), tq.getType());
		return qd;
	}

	@Override
	public int Chkansw(int RoomID, String answer) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		return Base.getRoom(RoomID).ChkAnsw(answer, UserID);
	}

	@Override
	public InfoDTO getInfo(int RoomID) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		Info info = Base.getRoom(RoomID).getInfo(UserID);
		InfoDTO qd = new InfoDTO(info.getQ().getQuestion(), info.getQ()
				.getAnswer(), info.getQ().getLabelsNames(), info.getQ()
				.getNumOfRank(), info.getQ().getRank(), info.getQ()
				.getNumOfСomplexity(), info.getQ().getComplexity(), info.getQ()
				.getIterations(), info.getQ().getChecked(), info.getQ()
				.getAuthorName(), info.getQ().getType(), info.getWinners(),
				info.getNextTime() - new Date().getTime(), info.getDuration(),
				info.getQ().getProvider());
		return qd;
	}

	@Override
	public int setComplaint(int RoomID, int type) {
		Long UserID = (Long) this.getThreadLocalRequest().getSession()
				.getAttribute("user");
		return Base.getRoom(RoomID).setComplaint(UserID, type);
	}
}
